package com.swak.boot.config.zookeeper.config;

import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;

import com.swak.boot.config.zookeeper.ZookeeperProperties;
import com.swak.boot.config.zookeeper.ZookeeperBuilder;
import com.swak.config.ConfigService;
import com.swak.utils.Fmt;
import com.swak.utils.StringUtils;
import com.swak.zookeeper.ZookeeperConfig;

/**
 * 从 Zookeeper 拉取配置.
 * 
 * @author 618lf
 */
public class ConfigEnvPostProcessor implements EnvironmentPostProcessor, Ordered {

	private ConfigurableEnvironment environment;
	private ConfigService configService;
	private ConfigDataLoader configDataLoader;

	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
		this.environment = environment;
		this.configDataLoader = new ConfigDataLoader(environment);
		String enableZk = environment.getProperty("spring.application.enableZk");
		if (!(StringUtils.isNotBlank(enableZk) && "true".equals(enableZk))) {
			return;
		}
		ZookeeperProperties properties = this.configDataLoader.getProperties();
		try {
			this.configService = new ZookeeperConfig( ZookeeperBuilder.build(properties));
		} catch (InterruptedException e) {
			throw new IllegalStateException("初始化配置中心异常", e);
		}
		Fmt.out.println("Loading Global Config：");
		for (String context : this.configDataLoader.getContexts()) {
			this.loadConig(context);
		}
	}

	private void loadConig(String path) {
		StringBuilder message = new StringBuilder();
		try {
			message.append("Load Conifg ").append(path);
			String configs = this.configService.getConfig(path);
			this.addPropertySource(path, configs);
			message.append(" Success.");
		} catch (Exception e) {
			message.append(" Not Found.");
		}
		Fmt.out.println(message);
	}

	private void addPropertySource(String path, String configs) throws IOException {
		if (StringUtils.isBlank(configs)) {
			return;
		}
		Properties properties = new Properties();
		properties.load(new StringReader(configs));
		PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource(path, properties);
		this.environment.getPropertySources().addFirst(propertiesPropertySource);
	}

	@Override
	public int getOrder() {
		return LOWEST_PRECEDENCE;
	}
}